using System.Linq;
using Pgvector;
using Microsoft.EntityFrameworkCore;
using Pgvector.EntityFrameworkCore;
using UniversalAdminSystem.Domian.FileStorage.ValueObjects;
using UniversalAdminSystem.Domian.knowledge.Aggregates;
using UniversalAdminSystem.Domian.knowledge.IRepository;
using UniversalAdminSystem.Domian.knowledge.ValueObj;
using UniversalAdminSystem.Infrastructure.Persistence.DbContexts;

namespace UniversalAdminSystem.Infrastructure.Persistence.Repositories;

public class DocumentChunkRepository : BaseRepository<DocumentChunk>, IDocumentChunkRepository
{
    public DocumentChunkRepository(UniversalAdminSystemDbContext dbContext) : base(dbContext)
    {
    }

    public async Task BatchDeleteDocumentChunkAsync(Guid Id)
    {
        var fileid = FileId.Create(Id);
        await _TDs.Where(d => d.FileId == fileid).ExecuteDeleteAsync();
    }

    public async Task BatchModificationChunkLevelAsync(Guid fileId, FileAccessLevel level)
    {
        var filesid = FileId.Create(fileId);
        await _TDs.Where(d => d.FileId == filesid)
                .ExecuteUpdateAsync(
                    set =>
                    set.SetProperty(d => d.Level, level)
                );
    }

    public async Task BulkAddDocumentChunkAsync(IEnumerable<DocumentChunk> chunks)
    {
        await _TDs.AddRangeAsync(chunks);
    }

    public async Task<IEnumerable<DocumentChunk>> FindSimilarDocumentsAsync(TextEmbedding queryEmbedding, FileAccessLevel level, int topK = 5)
    {
        if (queryEmbedding == null)
        {
            throw new ArgumentNullException(nameof(queryEmbedding), "Query embedding cannot be null");
        }

        // 确保 _TDs 是非空的
        if (_TDs == null)
        {
            throw new InvalidOperationException("Document data set (_TDs) is not initialized.");
        }


        try
        {
            var results = await _TDs
                        .Where(c => c.Level <= level) // 根据权限级别过滤
                        .OrderBy(c => c.Embedding.CosineDistance(new Vector(queryEmbedding.Value))) // 根据相似度排序
                        .Take(topK) // 限制返回的文档数量
                        .ToListAsync(); // 异步执行查询
            return results;
        }
        catch (Exception ex)
        {
            // 捕获并记录错误
            System.Console.WriteLine($"Error during document retrieval: {ex.Message}");
            return Enumerable.Empty<DocumentChunk>(); // 返回一个空的集合以避免进一步的错误
        }
    }

    public async Task<bool> ExistsByFileIdAsync(Guid fileId)
    {
        var fileid = FileId.Create(fileId);
        return await _TDs
            .AsNoTracking()
            .AnyAsync(x => x.FileId == fileid);
    }
}